package com.misboot.document.controller;

import cn.ewsd.common.controller.BaseController;
import com.misboot.document.constants.DriverClassName;
import com.misboot.document.service.RedisService;
import org.apache.commons.configuration.Configuration;
import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.PropertiesConfiguration;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.ParserContext;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.stereotype.Controller;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;


/**
 * 基础BaseController
 *
 * @Author 湖南佐佑时代科技有限公司
 * @Version 5.4.21
 * @Email service@zuoyo.com
 * @Date 2022-06-13 09:39:40
 */
@RefreshScope
@Controller
public class DocumentBaseController extends BaseController{

    @Value("${spring.datasource.dynamic.datasource.master.driver-class-name:null}")
    public String driverClassName;

    @Value("${spring.application.name}")
    public String applicationName;


    @Value("${spring.datasource.dynamic.datasource.master.url:null}")
    public String url;

    @Autowired
    private RedisService redisService;
    public Configuration getConfig(String fileName) {
        try {
            return new PropertiesConfiguration(fileName);
        } catch (ConfigurationException e) {
            throw new RuntimeException("获取配置文件失败，", e);
        }
    }

    public Boolean executeSql(String sql) {
        Connection conn = null;
        Statement st = null;
        try {
            Configuration config = getConfig("config.properties");
            String dbDriver = config.getString("mysql.jdbc.driverClassName");
            String dbUrl = config.getString("system.jdbc.url");
            String dbUsername = config.getString("system.jdbc.username");
            String dbPassword = config.getString("system.jdbc.password");

            //注册jdbc驱动
            Class.forName(dbDriver);
            //打开连接
            conn = DriverManager.getConnection(dbUrl, dbUsername, dbPassword);
            st = conn.createStatement();
            st.addBatch(sql);
            st.executeBatch();
            return true;
        } catch (Exception e) {
            System.out.println(e.getMessage());
            return false;
        } finally {
            try {
                if (st != null) st.close();
                if (conn != null) conn.close();
            } catch (Exception ex) {
                System.out.println("连接关闭异常！");
            }
        }
    }

    /**
     * 通用数据权限过滤
     *
     * @return
     */
    public String getAuthFilter() {
        // 获取当前角色的ID
        if (getCurrentRoleId() != null) {
            String[] roleIdArr = getCurrentRoleId().split(",");
            List<Map<String, Object>> authList = new ArrayList<>();
            for (int i = 0; i < roleIdArr.length; i++) {
                if (roleIdArr[i] != null && !roleIdArr[i].isEmpty()) {
                    authList.addAll(redisService.getDataAuthListFromCache(roleIdArr[i],driverClassName));
                }
            }
            //获取与当前访问数据接口一致的数据接口（有多条使用优先级最高的一条，数字越大优先级越高）的SQL字符串
            String url = "/" + applicationName + request.getRequestURI();

            // 获取所有的角色权限
            ArrayList<String> authArr = new ArrayList<String>();
            String rule_sql = "";
            String rule_url = "";
            for (int i = 0; i < authList.size(); i++) {
                if (DriverClassName.ORACLE_NAME.equals(driverClassName)) {
                    rule_sql = String.valueOf(authList.get(i).get("RULE_SQL"));
                    rule_url = String.valueOf(authList.get(i).get("RULE_HREF"));
                } else {
                    rule_sql = String.valueOf(authList.get(i).get("rule_sql"));
                    rule_url = String.valueOf(authList.get(i).get("rule_href"));
                }
                if (!authArr.contains(rule_sql) && rule_url.contains(url)) {
                    authArr.add(rule_sql);
                }
            }

            //解析器
            if (authArr.size() > 0) {
                String authStr = " AND (" + StringUtils.join(authArr, " or ") + ")";
                ExpressionParser parser = new SpelExpressionParser();
                StandardEvaluationContext context = new StandardEvaluationContext(this);
                ParserContext parserContext = new ParserContext() {
                    @Override
                    public boolean isTemplate() {
                        return true;
                    }

                    @Override
                    public String getExpressionSuffix() {
                        return "}";
                    }

                    @Override
                    public String getExpressionPrefix() {
                        return "${";
                    }
                };
                return parser.parseExpression(authStr, parserContext).getValue(context, String.class);
            }
        }
        return "";
    }
}
